package com.heima.search.service.impl;

import com.heima.es.service.EsService;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.dtos.UserSearchDTO;
import com.heima.model.search.vos.SearchArticleVO;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.pojos.ApUser;
import com.heima.search.service.ApUserSearchService;
import com.heima.search.service.ArticleSearchService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
public class ArticleSearchServiceImpl implements ArticleSearchService {
    public static final String APP_INFO_ARTICLE = "app_info_article";
    @Value("${file.minio.readPath}")
    String readPath;
    @Autowired
    EsService esService;
    @Autowired
    ApUserSearchService apUserSearchService;

    //ES文章分页搜索
    @Override
    public ResponseResult search(UserSearchDTO userSearchDto) {
        //参数检查
        String searchWords = userSearchDto.getSearchWords();
        if (userSearchDto == null || StringUtils.isBlank(searchWords)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //获取当前登录用户
        ApUser user = AppThreadLocalUtils.getUser();
        if(user !=null) userSearchDto.setEntryId(user.getId());

        //保存搜索关键字记录
        apUserSearchService.insert(userSearchDto);

        //创建查询条件对象SearchSourceBuilder
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //创建布尔查询条件对象
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //创建普通查询条件对象,根据title查询
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", searchWords);
        //将普通查询条件对象放入布尔查询条件对象,要求必须满足该条件
        boolQueryBuilder.must(queryBuilder);
        //创建等级查询条件对象,按照推送时间排序,查询小于MinBehotTime时间的数据
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("publishTime").lt(userSearchDto.getMinBehotTime().getTime());
        //将等级查询条件对象放入布尔查询条件对象进行过滤操作
        boolQueryBuilder.filter(rangeQueryBuilder);

        //设置分页参数,从第0个文档开始
        searchSourceBuilder.from(0);
        //设置分页参数,每页显示的条数
        searchSourceBuilder.size(userSearchDto.getPageSize());
        //搜索结果按照发布时间倒序排列
        searchSourceBuilder.sort("publishTime", SortOrder.DESC);
        //创建高亮条件对象
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        //设置高亮字段为title
        highlightBuilder.field("title");
        //preTags:设置高亮字段的前缀
        highlightBuilder.preTags("<font style='color: red; font-size: inherit;'>");
        //postTags:设置高亮字段的后缀
        highlightBuilder.postTags("</font>");
        //将高亮条件对象放入查询条件对象
        searchSourceBuilder.highlighter(highlightBuilder);
        //将布尔查询条件对象放入查询条件对象
        searchSourceBuilder.query(boolQueryBuilder);
        //使用工具类,将查询条件传入,返回分页查询结果
        PageResponseResult searchResult = esService.search(searchSourceBuilder, SearchArticleVO.class, APP_INFO_ARTICLE);
        //4 返回结果 staticUrl 需要拼接 minIO文章服务器的前缀路径
        List<SearchArticleVO> list = (List<SearchArticleVO>) searchResult.getData();
        if (CollectionUtils.isNotEmpty(list)) {
            for (SearchArticleVO searchArticleVo : list) {
                searchArticleVo.setStaticUrl(readPath + searchArticleVo.getStaticUrl());
            }
        }
        return searchResult;
    }

    //添加索引文章
    @Override
    public void saveArticle(SearchArticleVO article) {
        esService.save(article, APP_INFO_ARTICLE);
    }

    //删除索引文章
    @Override
    public void deleteArticle(String articleId) {
        esService.deleteById(APP_INFO_ARTICLE, articleId);
    }
}